/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: 

Purpose  : Handles all engine events to pass to owning objects
----------------------------------------------------------------------------*/

#pragma once

#include "core.h"
#include <vector>

/*--------------------------------------------------------------------------*/
// Class CSubsystem declaration.
class CSubsystem
{
public:
					CSubsystem(const char* i_name);

	const char*		GetName() const	{
						return m_name; }
	void			AddChildSubsystem(CSubsystem* i_child);
	bool			IsInitialized() const {
						return m_initialized; }
	bool			IsPostInitialized() const { 
						return m_postInitialized; }

	// init related
	void			DispatchInit();
	void			DispatchPostInit();

	// load/unload
	void			DispatchPreWorldLoad()	{ 
						OnPreWorldLoad(); broadcastChildren(&CSubsystem::DispatchPreWorldLoad); }
	void			DispatchPostWorldLoad()	{
						OnPostWorldLoad(); broadcastChildren(&CSubsystem::DispatchPostWorldLoad); }
	void			DispatchPreWorldUnload() {
						OnPreWorldUnload(); broadcastChildren(&CSubsystem::DispatchPreWorldUnload); }
	void			DispatchPostWorldUnload() {
						OnPostWorldUnload(); broadcastChildren(&CSubsystem::DispatchPostWorldUnload); }

	// update related
	void			DispatchPreWorldUpdate() { 
						OnPreWorldUpdate();	broadcastChildren(&CSubsystem::DispatchPreWorldUpdate); }
	void			DispatchPostWorldUpdate() {
						OnPostWorldUpdate(); broadcastChildren(&CSubsystem::DispatchPostWorldUpdate); }
	void			DispatchPostWorldRender() {
						OnPostWorldRender(); broadcastChildren(&CSubsystem::DispatchPostWorldRender); }
	void			DispatchPreIntroUpdate() { 
						OnPreIntroUpdate();	broadcastChildren(&CSubsystem::DispatchPreIntroUpdate); }
	void			DispatchPostIntroUpdate() {
						OnPostIntroUpdate(); broadcastChildren(&CSubsystem::DispatchPostIntroUpdate); }
	void			DispatchPostIntroRender() {
						OnPostIntroRender(); broadcastChildren(&CSubsystem::DispatchPostIntroRender); }		
	void			DispatchPreMapUpdate() { 
						OnPreMapUpdate();	broadcastChildren(&CSubsystem::DispatchPreMapUpdate); }
	void			DispatchPostMapUpdate() {
						OnPostMapUpdate(); broadcastChildren(&CSubsystem::DispatchPostMapUpdate); }
	void			DispatchPostMapRender() {
						OnPostMapRender(); broadcastChildren(&CSubsystem::DispatchPostMapRender); }		

protected:

// Event interface.

	virtual void OnInit()				{}
	virtual void OnPostInit()			{}

	virtual void OnPreWorldLoad()		{}
	virtual void OnPostWorldLoad()		{}
	virtual void OnPostPostWorldLoad()	{}
	virtual void OnPreWorldUnload()		{}
	virtual void OnPostWorldUnload()	{}

	virtual void OnPreWorldUpdate()		{}
	virtual void OnPostWorldUpdate()	{}
	virtual void OnPostWorldRender()	{}
	
	virtual void OnPreIntroUpdate()		{}
	virtual void OnPostIntroUpdate()	{}
	virtual void OnPostIntroRender()	{}
	
	virtual void OnPreMapUpdate()		{}
	virtual void OnPostMapUpdate()		{}
	virtual void OnPostMapRender()		{}


private:

	typedef void (CSubsystem::*DispatchProc)();

	void					broadcastChildren(DispatchProc i_dispatchProc);

	const char*					m_name;
	bool						m_initialized;
	bool						m_postInitialized;
	std::vector<CSubsystem*>	m_children;
};

/*--------------------------------------------------------------------------*/


/*-----------------------------------EOF!-----------------------------------*/
